Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Perf drawFramwork #2474

Merged
merged 17 commits into from
Mar 26, 2018
Merged

Perf drawFramwork #2474

merged 17 commits into from
Mar 26, 2018

Conversation

etpinard
Copy link
Contributor

@etpinard etpinard commented Mar 13, 2018

Here are two perf commits in Cartesian.drawFramework that will help splom subplot generation. 🐎

At 400 subplots (or 20 splom dimensions 😏 ), these commits are able to speed up drawFramework from ~1000ms down under 200ms.

Note that it might be nice to make the new joinLayer from 7d881f6 a standard Lib function and replace all our selectAll().data([0]) with it. Waiting on @alexcjohnson before going through with it.

- replace Object.keys + for-loop with for-in
- replace slow subplots.indexOf
- to replace expensive querySelectorAll with plain querySelector
@alexcjohnson
Copy link
Collaborator

Wow, I would not have guessed that those two were such a big drain, impressive find! Yes please, 🔪 all the selectAll(...).data([0])! The name joinLayer has never meant much to me though... I suppose I'd get used to it, but what about something like Lib.ensureSingle?

@etpinard
Copy link
Contributor Author

I suppose I'd get used to it, but what about something like Lib.ensureSingle

I like the sound of ensureSingle. Thanks!

- meant to replace all our `selectAll().data([0])` calls
  by something DRYer and faster.
- note that one test suite had to be updated, simply
  because ensureSingle adds class names in a different
  order than previously.
.each(function() {
var container = Lib.ensureSingle(fullLayout._infolayer, 'g', id, function(s) {
s.classed(cn.colorbar, true);
s.each(function() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't like chaining here? ie

s.classed(...)
    .each(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in -> 8e6032d

- this appear to be no longer needed
- adapt plot_api test to relied on layoutStyles spy counts
expect(node.classList[0]).toBe('drag');
expect(node.classList[1]).toBe('nwdrag');
expect(node.classList[1]).toBe('drag');
expect(node.classList[0]).toBe('nwdrag');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK as is, but this seems ripe for a custom matcher like:

expect(node).toBeClassed(['drag', 'nwdrag', 'cursor-nw-resize']);

That would be order-independent but also verify these are the only classes applied.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call.

cartesian_test.js uses assertions like:

expect(fills[0].classList.contains('js-tozero')).toBe(true)

which could work here too, but yeah checking adding a custom assertion that test multiple class names at once should be worthwhile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in b974eab

@@ -245,9 +245,7 @@ exports.plot = function(gd, data, layout, config) {
.attr('height', fullLayout.height);
}

return Lib.syncOrAsync([
subroutines.layoutStyles
], gd);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too funny, so it just works! We may never know what obviated this...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just worksTM

return Lib.syncOrAsync([
subroutines.layoutStyles
], gd);
return Plots.previousPromises(gd);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexcjohnson tests are ✅ after removing the extra layoutStyles call. Good riddance ⛵

... even though don't look bad to etpinard's 👀
- to easily test all items in class list while not
  having to worry about class name ordering.
@alexcjohnson
Copy link
Collaborator

Beautiful! 💃 💃 💃

@etpinard
Copy link
Contributor Author

Ok. This probably deserves to be in the next minor release 1.36.0, so I'll wait a few more days in case we need to make another patch release in 1.35.x series.

@etpinard etpinard added this to the v1.36.0 milestone Mar 14, 2018
... so that we don't have to traverse the DOM whenever
    we add a clipPath url 🐎
.. so that in the event where window.location changes on pages
   with a <base>, our clip path urls will be properly updated.
- this can speed up Axes.doTicks by 50ms on 50x50 subplots grids
- so that drawTitle() can reuse it
- this can speed up doTicks by 200ms at 50x50 subplots
More optimization for cartesian subplots
@etpinard etpinard merged commit 9a79056 into master Mar 26, 2018
@etpinard etpinard deleted the perf-drawFramwork branch March 26, 2018 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants